package com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzxczh.base.remote.RemoteService;
import com.css.fxfzxczh.base.response.RestResponse;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.casualties.entity.ypg.BuildingVulnerability;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.casualties.entity.ypg.DataPbeIntStrArea;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.casualties.entity.ypg.VulnerabilityVO;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.casualties.param.EvaluateParam;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.fastSeismicInfluence.service.IntensityAttenuationService;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.entity.HouseDestroyEvaluateModel;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.entity.HouseDestroyEvaluateResult;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.param.HouseEvaluateParam;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.repository.HouseDestroyRepository;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.vo.DataPbeInjuriesVo;
import com.css.fxfzxczh.modules.fastDisasterAnalysis.houseDestroy.vo.XczhDataGetByDataVersionAndGeomVo;
import com.css.fxfzxczh.modules.synthesizeInfoManage.earEveManage.entity.EarEveManage;
import com.css.fxfzxczh.modules.synthesizeInfoManage.earEveManage.service.EarEveManageService;
import com.css.fxfzxczh.util.PlatformObjectUtils;
import com.css.fxfzxczh.util.PlatformSessionUtils;
import com.css.fxfzxczh.util.ResponseCreator;
import com.css.fxfzxczh.util.UUIDGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Dbj
 * @date 2023年07月28日  15:38
 */
@Service
public class HouseDestroyService {

    @Resource
    IntensityAttenuationService intensityAttenuationService;
    @Value("${jcsj.url}")
    private String jcsjUrl;
    @Value("${fxfzypg.url}")
    private String fxfzypgUrl;
    @Resource
    RemoteService remoteService;
    @Resource
    HouseDestroyRepository houseDestroyRepository;
    @Resource
    EarEveManageService earEveManageService;

    public static final int BATCH_SIZE = 100000;

    public RestResponse countIntensityAndStructureOfArea(HouseEvaluateParam evaluateParam) throws Exception {
        Long start = System.currentTimeMillis();
        //刪除相同地震事件生成的数据
        houseDestroyRepository.deleteDataPbeIntStrAreaByXsemId(evaluateParam.getXsemId());
        //获取同一地震事件下的所有影响场空间数据的并集
        String unionGeom = intensityAttenuationService.getUnionGeom(evaluateParam.getXsemId());
        if(StringUtils.isBlank(unionGeom)){
            throw new RuntimeException("评估失败,该地震事件下查询不到影响场信息");
        }
        //EarEveManage currentEvent = earEveManageService.getCurrentEvent();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("dataVersion",evaluateParam.getBuildingVersion());
        jsonObject.put("geom",unionGeom);
//        jsonObject.put("province", currentEvent.getProvince());
//        jsonObject.put("city",currentEvent.getCity());
//        jsonObject.put("county",currentEvent.getCounty());
        //远程调用基础数据系统接口获取建筑物和人口指定版本的格网信息
        final String url  = jcsjUrl+"/datacenter/jcDsGpbGdzcGridTotalHousing/xczhGetByDataVersionAndGeom";
        JSONArray jsonArray =  null;
        Long getGridStart = System.currentTimeMillis();
        try{
            jsonArray =  (JSONArray) remoteService.getJCSJ(url, 4, jsonObject).getData();
        }catch (Exception ex){
            ex.printStackTrace();
            throw new RuntimeException("评估失败，请先维护基础数据的建筑物格网数据");
        }
        Long getGridEnd = System.currentTimeMillis();
        System.out.println("远程基础数据获取建筑物格网数据所花费的时间为:"+(getGridEnd-getGridStart)/1000);
        if (PlatformObjectUtils.isEmpty(jsonArray) || jsonArray.size()==0){
            throw new RuntimeException("评估失败,请先维护基础数据的建筑物格网数据");
        }
        List<XczhDataGetByDataVersionAndGeomVo> gridList = JSON.parseArray(jsonArray.toJSONString(), XczhDataGetByDataVersionAndGeomVo.class);
        if(PlatformObjectUtils.isEmpty(gridList) || gridList.size()==0){
            throw new RuntimeException("评估失败,请先维护基础数据的建筑物格网数据");
        }
        String province = "";//省
        String city = "";//市
        String country = "";//县
        String town = "";//镇
        //key:地震烈度；value:建筑物易损性信息VO
        Map<String, List<VulnerabilityVO>> listMap = new HashMap<>();
        //建筑物易损性信息
        List<BuildingVulnerability> allVulnerability = new ArrayList<>();
        //格网数据
        List<DataPbeIntStrArea> pbeIntStrAreaList = new ArrayList<>();
        Map<String,List<BuildingVulnerability>> map = new HashMap<>();
        for (XczhDataGetByDataVersionAndGeomVo grid : gridList) {
            //每个格网的建筑物面积
            Double area = grid.getTotalArea();
            if(PlatformObjectUtils.isEmpty(area)){
                continue;
            }
            //每个格网的建筑面积
            BigDecimal totalArea = BigDecimal.valueOf(area);
            //钢结构建筑面积百分比(小数)
            BigDecimal steelRatio = PlatformObjectUtils.isEmpty(grid.getSteelratio()) || grid.getSteelratio()==0.0 ?BigDecimal.ZERO:(BigDecimal.valueOf(grid.getSteelratio()).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_UP));
            //钢筋混凝土结构建筑面积百分比(小数)
            BigDecimal reconRatio = PlatformObjectUtils.isEmpty(grid.getReconratio())||grid.getReconratio()==0.0?BigDecimal.ZERO:(BigDecimal.valueOf(grid.getReconratio()).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_UP));
            //砖混结构建筑面积百分比(小数)
            BigDecimal brickRatio = PlatformObjectUtils.isEmpty(grid.getBrickratio())||grid.getBrickratio()==0.0?BigDecimal.ZERO:(BigDecimal.valueOf(grid.getBrickratio()).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_UP));
            //木结构建筑面积百分比(小数)
            BigDecimal woodRatio = PlatformObjectUtils.isEmpty(grid.getWoodratio())||grid.getWoodratio()==0.0?BigDecimal.ZERO:(BigDecimal.valueOf(grid.getWoodratio()).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_UP));
            //其他结构建筑面积百分比(小数)
            BigDecimal otherRatio = PlatformObjectUtils.isEmpty(grid.getOtherratio())||grid.getOtherratio()==0.0?BigDecimal.ZERO:(BigDecimal.valueOf(grid.getOtherratio()).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_UP));

            //获取五种结构类型的面积  总面积*各个结构类型所占的比列
            //钢结构建筑面积
            BigDecimal steelArea = totalArea.multiply(steelRatio);
            //钢筋混凝土结构建筑面积
            BigDecimal reconArea = totalArea.multiply(reconRatio);
            //砖混结构建筑面积
            BigDecimal brickArea = totalArea.multiply(brickRatio);
            //木结构建筑面积
            BigDecimal woodArea = totalArea.multiply(woodRatio);
            //其他结构建筑面积
            BigDecimal otherArea = totalArea.multiply(otherRatio);
            //查询建筑物易损性数据 每个省市县只查询一次数据库
            if(map.containsKey(grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty())){
                allVulnerability = map.get(grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty());
            }else{
                System.out.println("11111");
                Long getVulnerabilityStart = System.currentTimeMillis();
                allVulnerability  = getBuildingGridDataVersionList(grid);
                System.out.println("远程ypg获取建筑物易损性数据花费时间为:"+(System.currentTimeMillis()-getVulnerabilityStart)/1000);
               // if(PlatformObjectUtils.isEmpty(allVulnerability) || allVulnerability.size()==0){
                    //continue;
                    //throw new RuntimeException("评估失败，请到预评估系统维护"+grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty()+"的建筑物易损性数据");
                //}
                map.put(grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty(),allVulnerability);
            }
            if(allVulnerability.size()>0){
                List<String> collect = allVulnerability.stream().map(BuildingVulnerability::getStructureType).collect(Collectors.toList());
                if(collect.size()<0){
                    throw new RuntimeException("计算未完成，请检查是否维护完全钢结构、多层钢筋混凝十结构、砖混结构、木结构、其他结构的易损性数据");
                }
                //改造allVulnerability
                Map<String, Object> rebuild = rebuild(allVulnerability);
                if (!rebuild.get("code").equals("200")) {
                    throw new RuntimeException(String.valueOf(rebuild.get("msg")));
                }
                listMap = (Map<String, List<VulnerabilityVO>>) rebuild.get("listMap");
            }

            for (int i = 6; i < 11; i++) {
                if (PlatformObjectUtils.isNotEmpty(allVulnerability)) {
                    if(listMap!=null){
                        List<VulnerabilityVO> vulnerabilityVOS = listMap.get(String.valueOf(i));
                        if(PlatformObjectUtils.isNotEmpty(vulnerabilityVOS)){
                            for (VulnerabilityVO vo : vulnerabilityVOS) {
                                BigDecimal tsteelArea = steelArea.multiply(vo.getZero());
                                BigDecimal treconArea = reconArea.multiply(vo.getOne());
                                BigDecimal tbrickArea = brickArea.multiply(vo.getTwo());
                                BigDecimal twoodArea = woodArea.multiply(vo.getThree());
                                BigDecimal totherArea = otherArea.multiply(vo.getFour());
                                DataPbeIntStrArea pbeIntStrArea = new DataPbeIntStrArea();

                                pbeIntStrArea.setId(UUIDGenerator.getUUID()).setPbeId(grid.getJdgggthId())
                                        .setDzIntensity(String.valueOf(i)).setXsemId(evaluateParam.getXsemId()).setGeom(grid.getGeom())
                                        .setSteelArea(tsteelArea).setCArea(treconArea).setBArea(tbrickArea).setWArea(twoodArea).setOArea(totherArea)
                                        .setDestroy(vo.getDestroy()).setCoveredArea(BigDecimal.valueOf(area)).setProvince(grid.getProvince())
                                        .setCity(grid.getCity()).setCounty(grid.getCounty()).setTown(grid.getTown())
                                        .setProvinceCode(String.valueOf(grid.getFxpcXzqhbmaSjgl())).setCityCode(String.valueOf(grid.getFxpcXzqhbmbSjgl()))
                                        .setCountyCode(String.valueOf(grid.getFxpcXzqhbmcSjgl()));
                                pbeIntStrAreaList.add(pbeIntStrArea);
                            }
                        }
                    }
                } else {
                    for (int j = 0; j < 5; j++) {
                        DataPbeIntStrArea pbeIntStrArea = new DataPbeIntStrArea();
                        pbeIntStrArea.setId(UUIDGenerator.getUUID()).setPbeId(grid.getJdgggthId())
                                .setDzIntensity(String.valueOf(i)).setXsemId(evaluateParam.getXsemId()).setGeom(grid.getGeom())
                                .setSteelArea(BigDecimal.ZERO).setCArea(BigDecimal.ZERO).setBArea(BigDecimal.ZERO).setWArea(BigDecimal.ZERO).setOArea(BigDecimal.ZERO)
                                .setDestroy(String.valueOf(j))
                                .setCoveredArea(BigDecimal.valueOf(area)).setProvince(grid.getProvince())
                                .setCity(grid.getCity()).setCounty(grid.getCounty()).setTown(grid.getTown())
                                .setProvinceCode(String.valueOf(grid.getFxpcXzqhbmaSjgl())).setCityCode(String.valueOf(grid.getFxpcXzqhbmbSjgl()))
                                .setCountyCode(String.valueOf(grid.getFxpcXzqhbmcSjgl()));
                        pbeIntStrAreaList.add(pbeIntStrArea);
                    }
                }
            }
        }
        System.out.println(pbeIntStrAreaList.size()+ "开始插入");
        //一次10万条
        int fromIndex = 0; int toIndex = BATCH_SIZE;
        while (fromIndex != pbeIntStrAreaList.size()) {
            if (toIndex > pbeIntStrAreaList.size()) {
                toIndex = pbeIntStrAreaList.size();
            }
            List<DataPbeIntStrArea> list = pbeIntStrAreaList.subList(fromIndex, toIndex);
            int insertcount = houseDestroyRepository.batchupdate(list);
            System.out.println("插入成功"+insertcount );
            fromIndex = toIndex;
            toIndex += BATCH_SIZE;
            if (toIndex > pbeIntStrAreaList.size()){
                toIndex = pbeIntStrAreaList.size();
            }
        }
        System.out.println("保存格网时间花费" + (System.currentTimeMillis() - start) / 1000);
        return ResponseCreator.createSuccessResponse("计算成功!");
    }

    private Map<String, Object> rebuild(List<BuildingVulnerability> allVulnerability) {
        Map<String, Object> map = null;
        List<String> list = new ArrayList<>();//存储 结构类型+破坏程度，用以判断是否重复
        Map<String, List<VulnerabilityVO>> listMap = new HashMap<>();
        List<VulnerabilityVO> voList1 = null;
        List<VulnerabilityVO> voList2 = null;
        List<VulnerabilityVO> voList3 = null;
        List<VulnerabilityVO> voList4 = null;
        List<VulnerabilityVO> voList5 = null;
        //只计算钢结构、多层钢筋混凝土、砖混、木和其他结构的
        for (int i =0;i< allVulnerability.size(); ) {
            BuildingVulnerability buildingVulnerability1 = allVulnerability.get(i);
            BuildingVulnerability buildingVulnerability2 = allVulnerability.get(i+1);
            BuildingVulnerability buildingVulnerability3 = allVulnerability.get(i+2);
            BuildingVulnerability buildingVulnerability4 = allVulnerability.get(i+3);
            BuildingVulnerability buildingVulnerability5 = allVulnerability.get(i+4);
            VulnerabilityVO vo = new VulnerabilityVO();

            if (listMap.containsKey("6")) {
                voList1 = listMap.get("6");
            } else {
                voList1 = new ArrayList<>();
            }
            String destroy = buildingVulnerability1.getDestroy();
            vo.setDestroy(destroy);
            if ("1".equals(buildingVulnerability1.getStructureType())) {
                map = isRepeat(list, "6", buildingVulnerability1.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setZero(buildingVulnerability1.getSix());
                i++;
            }

            if ("2".equals(buildingVulnerability2.getStructureType())) {
                map = isRepeat(list, "6", buildingVulnerability2.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setOne(buildingVulnerability2.getSix());
                i++;
            }

            if ("3".equals(buildingVulnerability3.getStructureType())) {
                map = isRepeat(list, "6", buildingVulnerability3.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setTwo(buildingVulnerability3.getSix());
                i++;
            }

            if ("6".equals(buildingVulnerability4.getStructureType())) {
                map = isRepeat(list, "6", buildingVulnerability4.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setThree(buildingVulnerability4.getSix());
                i++;
            }

            if ("8".equals(buildingVulnerability5.getStructureType())) {
                map = isRepeat(list, "6", buildingVulnerability5.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setFour(buildingVulnerability5.getSix());
                i++;
            }
            voList1.add(vo);
            listMap.put("6", voList1);

            //烈度7
            if (listMap.containsKey("7")) {
                voList2 = listMap.get("7");
            } else {
                voList2 = new ArrayList<>();
            }
            vo = new VulnerabilityVO();
            vo.setDestroy(destroy);
            if ("1".equals(buildingVulnerability1.getStructureType())) {
                map = isRepeat(list, "7", buildingVulnerability1.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setZero(buildingVulnerability1.getSeven());
            }

            if ("2".equals(buildingVulnerability2.getStructureType())) {
                map = isRepeat(list, "7", buildingVulnerability2.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setOne(buildingVulnerability2.getSeven());
            }

            if ("3".equals(buildingVulnerability3.getStructureType())) {
                map = isRepeat(list, "7", buildingVulnerability3.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setTwo(buildingVulnerability3.getSeven());
            }

            if ("6".equals(buildingVulnerability4.getStructureType())) {
                map = isRepeat(list, "7", buildingVulnerability4.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setThree(buildingVulnerability4.getSeven());
            }

            if ("8".equals(buildingVulnerability5.getStructureType())) {
                map = isRepeat(list, "7", buildingVulnerability5.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setFour(buildingVulnerability5.getSeven());
            }
            voList2.add(vo);
            listMap.put("7", voList2);

            //烈度8
            if (listMap.containsKey("8")) {
                voList3 = listMap.get("8");
            } else {
                voList3 = new ArrayList<>();
            }
            vo = new VulnerabilityVO();
            vo.setDestroy(destroy);
            if ("1".equals(buildingVulnerability1.getStructureType())) {
                map = isRepeat(list, "8", buildingVulnerability1.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setZero(buildingVulnerability1.getEight());
            }

            if ("2".equals(buildingVulnerability2.getStructureType())) {
                map = isRepeat(list, "8", buildingVulnerability2.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setOne(buildingVulnerability2.getEight());
            }

            if ("3".equals(buildingVulnerability3.getStructureType())) {
                map = isRepeat(list, "8", buildingVulnerability3.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setTwo(buildingVulnerability3.getEight());
            }

            if ("6".equals(buildingVulnerability4.getStructureType())) {
                map = isRepeat(list, "8", buildingVulnerability4.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setThree(buildingVulnerability4.getEight());
            }

            if ("8".equals(buildingVulnerability5.getStructureType())) {
                map = isRepeat(list, "8", buildingVulnerability5.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setFour(buildingVulnerability5.getEight());
            }
            voList3.add(vo);
            listMap.put("8", voList3);

            //烈度9
            if (listMap.containsKey("9")) {
                voList4 = listMap.get("9");
            } else {
                voList4 = new ArrayList<>();
            }
            vo = new VulnerabilityVO();
            vo.setDestroy(destroy);
            if ("1".equals(buildingVulnerability1.getStructureType())) {
                map = isRepeat(list, "9", buildingVulnerability1.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setZero(buildingVulnerability1.getNine());
            }

            if ("2".equals(buildingVulnerability2.getStructureType())) {
                map = isRepeat(list, "9", buildingVulnerability2.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setOne(buildingVulnerability2.getNine());
            }

            if ("3".equals(buildingVulnerability3.getStructureType())) {
                map = isRepeat(list, "9", buildingVulnerability3.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setTwo(buildingVulnerability3.getNine());
            }

            if ("6".equals(buildingVulnerability4.getStructureType())) {
                map = isRepeat(list, "9", buildingVulnerability4.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setThree(buildingVulnerability4.getNine());
            }

            if ("8".equals(buildingVulnerability5.getStructureType())) {
                map = isRepeat(list, "9", buildingVulnerability5.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setFour(buildingVulnerability5.getNine());
            }
            voList4.add(vo);
            listMap.put("9", voList4);

            //烈度10
            if (listMap.containsKey("10")) {
                voList5 = listMap.get("10");
            } else {
                voList5 = new ArrayList<>();
            }
            vo = new VulnerabilityVO();
            vo.setDestroy(destroy);
            if ("1".equals(buildingVulnerability1.getStructureType())) {
                map = isRepeat(list, "10", buildingVulnerability1.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setZero(buildingVulnerability1.getTen());
            }

            if ("2".equals(buildingVulnerability2.getStructureType())) {
                map = isRepeat(list, "10", buildingVulnerability2.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setOne(buildingVulnerability2.getTen());
            }

            if ("3".equals(buildingVulnerability3.getStructureType())) {
                map = isRepeat(list, "10", buildingVulnerability3.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setTwo(buildingVulnerability3.getTen());
            }

            if ("6".equals(buildingVulnerability4.getStructureType())) {
                map = isRepeat(list, "10", buildingVulnerability4.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setThree(buildingVulnerability4.getTen());
            }

            if ("8".equals(buildingVulnerability5.getStructureType())) {
                map = isRepeat(list, "10", buildingVulnerability5.getStructureType(), destroy);
                if (map != null) {
                    return map;
                }
                vo.setFour(buildingVulnerability5.getTen());
            }
            voList5.add(vo);
            listMap.put("10", voList5);
        }
        map = new HashMap<>();
        map.put("code", "200");
        map.put("listMap", listMap);
        return map;
    }
    private Map<String, Object> isRepeat(List<String> list, String dzIntensity, String structureType, String destroy) {
        Map<String, Object> map = new HashMap<>();
        if (list.contains(dzIntensity + "-" + structureType + "-" + destroy)) {
            map.put("code", "500");
            switch (structureType) {
                case "0":
                    structureType = "高层结构";
                    break;
                case "1":
                    structureType = "钢结构";
                    break;
                case "2":
                    structureType = "混凝土结构";
                    break;
                case "3":
                    structureType = "砖混结构";
                    break;
                case "4":
                    structureType = "砖木结构";
                    break;
                case "5":
                    structureType = "土结构";
                    break;
                case "6":
                    structureType = "木结构";
                    break;
                case "7":
                    structureType = "石结构";
                    break;
                case "8":
                    structureType = "其他结构";
                    break;
            }
            switch (destroy) {
                case "0":
                    destroy = "基本完好";
                    break;
                case "1":
                    destroy = "轻微破坏";
                    break;
                case "2":
                    destroy = "中等破坏";
                    break;
                case "3":
                    destroy = "严重破坏";
                    break;
                case "4":
                    destroy = "毁坏";
                    break;
            }
            map.put("msg", "建筑物易损性烈度为" + dzIntensity + "的" + structureType + "的" + destroy + "的破坏程度的数据有异常！");
            return map;
        }
        list.add(dzIntensity + "-" + structureType + "-" + destroy);
        return null;
    }
    private List<BuildingVulnerability> getBuildingGridDataVersionList(XczhDataGetByDataVersionAndGeomVo grid) throws Exception {
        final String ypgUrl = fxfzypgUrl+"/buildingVulnerability/remoteGetAllVulnerabilityOrder?province="+grid.getProvince()+"&city="+grid.getCity()+"&county="+grid.getCounty()+"&source="+"1,2,3,6,8";
        JSONObject valueMap = new JSONObject();
        Object data = null;
        try{
            data = remoteService.getJCSJ(ypgUrl, 3, valueMap).getData();
        }catch (Exception ex){
            ex.printStackTrace();
            return null;
            //throw new RuntimeException("评估失败，无法从预评估系统获取"+grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty()+"下的建筑物易损性数据");
        }
        if(data==null){
            //throw new RuntimeException("评估失败，查询不到"+grid.getProvince()+"-"+grid.getCity()+"-"+grid.getCounty()+"下的建筑物易损性数据");
//            //todo 需要打开throw的注释
            return null;
        }
        JSONArray jsonArray = (JSONArray) data;
        return  JSON.parseArray(jsonArray.toJSONString(), BuildingVulnerability.class);
    }

    private Map<String, String> buildIntensityRelation() {
        Map<String, String> map = new HashMap<>();
        map.put("6","Ⅵ");
        map.put("7","Ⅶ");
        map.put("8","Ⅷ");
        map.put("9","Ⅸ");
        map.put("10","Ⅹ");
        return map;
    }
    @Transactional(rollbackFor = Exception.class)
    public void evaluate(EvaluateParam param) {
        //先删除模型数据
        houseDestroyRepository.deleteHouseEvaluateModel(param.getXsemId());
        //保存模型信息
        String xfhemId = saveHouseDestroyEvaluateModel(param);
        //删除之前生成的额评估数据
        houseDestroyRepository.deleteHouseEvaluateResult(param.getXsemId());
        //根据地震事件id获取地震下的所有的影响场（椭圆）下的同一个地震烈度的格网的破坏面积
        List<DataPbeInjuriesVo> voList = houseDestroyRepository.getPbeInjuriesByXsemId(param.getXsemId());
        if (PlatformObjectUtils.isEmpty(voList)) {
            throw new RuntimeException("计算失败,该任务尚未生成影响场!");
        }
        //如果存在一个格网跨越不同的烈度则保留相交面积最大的格网，并按照地震烈度进行分组
        Map<String, List<DataPbeInjuriesVo>> distinctPbeDateList = distinctPbeDateList(voList);
        //distinctPbeDateList的k是烈度 v是该烈度下的格网数据
        List<HouseDestroyEvaluateResult> list = new ArrayList<>();
        distinctPbeDateList.forEach((k,v)->{
            //一个烈度保存一份数据
            HouseDestroyEvaluateResult result = new HouseDestroyEvaluateResult();
            result.setXfherId(UUIDGenerator.getUUID());
            result.setXsemId(param.getXsemId());
            result.setFsiId(param.getFvId());
            result.setDzIntensity(k);
            result.setIntensity(buildIntensityRelation().get(k));
            result.setInfluenceVersion(param.getInfluenceVersion());
            //查询影响场的空间数据
            String geom = intensityAttenuationService.getGeom(v.get(0).getFsiId());
            result.setGeom(geom);
            //totalArea是相同烈度下的所有格网面积之和
            BigDecimal totalArea = v.stream().filter(dataPbeInjuriesVo -> PlatformObjectUtils.isNotEmpty(dataPbeInjuriesVo.getCoveredArea())).map(DataPbeInjuriesVo::getCoveredArea).reduce(BigDecimal.ZERO,BigDecimal::add);
            result.setTotalArea(totalArea);
            //collectMap的key是破坏程度  ，v是该破坏程度下的格网数据
            Map<String, List<DataPbeInjuriesVo>> collectMap = v.stream().collect(Collectors.groupingBy(DataPbeInjuriesVo::getDestroy));
            collectMap.forEach((k1,v1)->{
                BigDecimal totalDestroyArea = BigDecimal.ZERO;
                for (DataPbeInjuriesVo dataPbeInjuriesVo : v1) {
                    totalDestroyArea = totalDestroyArea.add(PlatformObjectUtils.isEmpty(dataPbeInjuriesVo.getSteelArea())?BigDecimal.ZERO:BigDecimal.valueOf(dataPbeInjuriesVo.getSteelArea()));
                    totalDestroyArea = totalDestroyArea.add(PlatformObjectUtils.isEmpty(dataPbeInjuriesVo.getCArea())?BigDecimal.ZERO:BigDecimal.valueOf(dataPbeInjuriesVo.getCArea()));
                    totalDestroyArea = totalDestroyArea.add(PlatformObjectUtils.isEmpty(dataPbeInjuriesVo.getBArea())?BigDecimal.ZERO:BigDecimal.valueOf(dataPbeInjuriesVo.getBArea()));
                    totalDestroyArea = totalDestroyArea.add(PlatformObjectUtils.isEmpty(dataPbeInjuriesVo.getWArea())?BigDecimal.ZERO:BigDecimal.valueOf(dataPbeInjuriesVo.getWArea()));
                    totalDestroyArea = totalDestroyArea.add(PlatformObjectUtils.isEmpty(dataPbeInjuriesVo.getOArea())?BigDecimal.ZERO:BigDecimal.valueOf(dataPbeInjuriesVo.getOArea()));
                }
                BigDecimal percent = BigDecimal.ZERO;
                if(totalArea.compareTo(BigDecimal.ZERO)>0){
                    percent = totalDestroyArea.divide(totalArea, 4, RoundingMode.HALF_DOWN);
                }
                /**
                 *  0基本完好
                 *  1轻微破坏
                 *  2中等破坏
                 * 3严重破坏
                 * 4损坏
                 */
                if("0".equals(k1)){
                    result.setBasic(percent);
                    result.setBasicArea(totalDestroyArea);
                }else if("1".equals(k1)){
                    result.setSlight(percent);
                    result.setSlightArea(totalDestroyArea);
                }else if("2".equals(k1)){
                    result.setMid(percent);
                    result.setMidArea(totalDestroyArea);
                }else if("3".equals(k1)){
                    result.setSerious(percent);
                    result.setSeriousArea(totalDestroyArea);
                }else if("4".equals(k1)){
                    result.setDestroy(percent);
                    result.setDestroyArea(totalDestroyArea);
                }
            });
            result.setXfhemId(xfhemId);
            list.add(result);
        });
        if(list.size()>0){
            houseDestroyRepository.batchSave(list);
        }
    }

    private String saveHouseDestroyEvaluateModel(EvaluateParam param) {
        HouseDestroyEvaluateModel model = new HouseDestroyEvaluateModel();
        String xfhemId = UUIDGenerator.getUUID();
        model.setXfhemId(xfhemId);
        model.setBuildingVersion(param.getBuildingVersion());
        model.setInfluenceVersion(param.getInfluenceVersion());
        model.setFvId(param.getFvId());
        model.setEvaluateUser(PlatformSessionUtils.getUserId());
        model.setEvaluateTime(new Date());
        model.setXsemId(param.getXsemId());
        houseDestroyRepository.saveHouseDestroyEvaluateModel(model);
        return xfhemId;
    }

    private Map<String, List<DataPbeInjuriesVo>> distinctPbeDateList(List<DataPbeInjuriesVo> voList) {
        //list保存的是所有不重复的网格数据
        List<DataPbeInjuriesVo> list = new ArrayList<>();
        //按照格网分组
        Map<String, List<DataPbeInjuriesVo>> listMap = voList.stream().collect(Collectors.groupingBy(DataPbeInjuriesVo::getPbeId));
        listMap.forEach((k,v)->{
            //按照影响场烈度圈id分组 collect的value相同的格网跨越不同的烈度 也就是不同烈度中存在相同的格网数据
            Map<String, List<DataPbeInjuriesVo>> collect = v.stream().collect(Collectors.groupingBy(DataPbeInjuriesVo::getFsiId));
            if(collect.values().size()>1){
                 //表示一个网格跨越不同的烈度圈
                List<DataPbeInjuriesVo> tempList = null;
                Iterator<Map.Entry<String, List<DataPbeInjuriesVo>>> iterator = collect.entrySet().iterator();
                while(iterator.hasNext()){
                    Map.Entry<String, List<DataPbeInjuriesVo>> next = iterator.next();
                    List<DataPbeInjuriesVo> value = next.getValue();
                    if(tempList==null){
                        tempList = value;
                    }else{
                        DataPbeInjuriesVo dataPbeInjuriesVo = tempList.get(0);
                        DataPbeInjuriesVo dataPbeInjuriesVo1 = value.get(0);
                        //当同一个格网跨越不同烈度时判断该格网的归属问题，在哪个烈度中的相交面积越大则该格网归属哪个烈度
                        if(dataPbeInjuriesVo.getArea()<dataPbeInjuriesVo1.getArea()){
                            tempList = value;
                        }
                    }
                }
                list.addAll(tempList);
            }else{
                //表示一个网格只归属于一个烈度
                list.addAll(v);
            }
        });
        //获取不同烈度下的格网信息的集合
        Map<String, List<DataPbeInjuriesVo>> intensityMap = list.stream().collect(Collectors.groupingBy(DataPbeInjuriesVo::getDzIntensity));
        return intensityMap;
    }

    public RestResponse getHouseDestoryResult(String xsemId,String dzIntensity) {
        List<HouseDestroyEvaluateResult> results = houseDestroyRepository.getHouseDestoryResult(xsemId,dzIntensity);
        return ResponseCreator.createSuccessResponse(results);
    }

    public RestResponse getHouseDestoryAreaSum(String xsemId) {
        HouseDestroyEvaluateResult results = houseDestroyRepository.getHouseDestoryAreaSum(xsemId);
        return ResponseCreator.createSuccessResponse(results);
    }

    public HouseDestroyEvaluateModel getModelData(String xsemId) {
        return houseDestroyRepository.getModelData(xsemId);
    }


}
